package org.example.bean;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;
import java.io.IOException;

/**
 * 手动配置Mybatis数据源
 */
@Configuration
@Slf4j
public class DataSourceConfig {
    @Value("${spring.datasource.driver-class-name}")
    private String driverClass = "monitor.datasource.driver-class-name";
    @Value("${spring.datasource.url}")
    private String jdbcUrl = "monitor.datasource.url";
    @Value("${spring.datasource.username}")
    private String username = "monitor.datasource.username";
    @Value("${spring.datasource.password}")
    private String password = "monitor.datasource.password";

    /**
     * 初始化数据源
     *
     * @return dataSource
     */
    @Bean
    public DataSource dataSource() {
        // HikariCP连接池配置
        HikariConfig hikariConfig = new HikariConfig();
        hikariConfig.setDriverClassName(driverClass);
        hikariConfig.setJdbcUrl(jdbcUrl);
        hikariConfig.setUsername(username);
        hikariConfig.setPassword(password);
        log.info("build connectorPool complete");

        return new HikariDataSource(hikariConfig);
    }

    /**
     * 初始化SqlSessionFactory
     *
     * @return sqlSessionFactory
     * @throws IOException e
     */
    @Bean
    public SqlSessionFactoryBean sqlSessionFactory() throws IOException {
        SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
        sqlSessionFactory.setDataSource(dataSource());
        try {
            sqlSessionFactory.setMapperLocations(
                    new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
        } catch (IOException e) {
            log.error("unable to find mybatis mapper in resources dir.");
            throw new IOException(e);
        }
        // 开启驼峰转换, mybatis默认不会把数据库下划线转换成驼峰
        org.apache.ibatis.session.Configuration config = new org.apache.ibatis.session.Configuration();
        config.setMapUnderscoreToCamelCase(true);
        sqlSessionFactory.setConfiguration(config);

        return sqlSessionFactory;
    }

    /**
     * 初始化SqlSessionTemplate
     *
     * @param sqlSessionFactory SqlSessionFactory
     * @return sqlSessionFactory
     */
    @Bean
    public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

    /**
     * 初始化PlatformTransactionManager
     *
     * @return transactionManager
     */
    @Bean
    public PlatformTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dataSource());
    }
}